package com.panopset.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;

import com.panopset.Util;

/**
 * Handle small input and output streams.
 * @author Karl Dinwiddie
 *
 */
public final class StreamProcessor {

    /**
     * Read an InputStream.
     * @param is Input stream.
     * @return Results or empty String if there was a problem.
     */
    public static String getStream(final InputStream is) {
        BufferedInputStream bis = null;
        try {
            StringWriter sw = new StringWriter();
            bis = new BufferedInputStream(is);
            int i = bis.read();
            while (i != -1) {
                sw.append((char) i);
                i = bis.read();
            }
            return sw.toString();
        } catch (Exception ex) {
            Util.log(ex);
            return "";
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (Exception ex) {
                    Util.log(ex);
                }
            }
        }
    }

    /**
     * Copy stream.
     *
     * @param inputStream
     *            Input stream.
     * @param outputStream
     *            Output stream.
     * @throws IOException
     *             IO Exception.
     */
    public static void copyStream(final InputStream inputStream,
            final OutputStream outputStream) throws IOException {
        BufferedInputStream is = null;
        if (inputStream instanceof BufferedInputStream) {
            is = (BufferedInputStream) inputStream;
        } else {
            is = new BufferedInputStream(inputStream);
        }
        BufferedOutputStream os = null;
        if (outputStream instanceof BufferedOutputStream) {
            os = (BufferedOutputStream) outputStream;
        } else {
            os = new BufferedOutputStream(outputStream);
        }
        int b;
        while ((b = is.read()) != -1) {
            os.write(b);
        }
        os.flush();
        os.close();
        if (os != outputStream) {
            outputStream.flush();
            outputStream.close();
        }
        is.close();
        if (is != inputStream) {
            inputStream.close();
        }
    }

    /**
     * Buffer size.
     */
    private static final int BUFFER_SIZE = 1024;

    /**
     * Copy stream.
     *
     * @param is
     *            Input stream.
     * @param os
     *            Output stream.
     * @throws IOException
     *             IO Exception.
     */
    public static void copyStream(final InputStreamReader is,
            final OutputStreamWriter os) throws IOException {
        char[] buf = new char[BUFFER_SIZE];
        int len;
        while ((len = is.read(buf)) > 0) {
            os.write(buf, 0, len);
        }
        is.close();
        os.flush();
        os.close();
    }

    /**
     * Prevent instantiation.
     */
    private StreamProcessor() {
    }
}
